#include "Channel.h"

Channel::Channel(Epoll *epfd, int fd)
    : epfd_(epfd), fd_(fd)
{
}
Channel::~Channel()
{
    // 在析构函数中，不要销毁ep_，也不能关闭fd_，因为这两个东西不属于Channel类，Channel类只是需要它们，使用它们而已。
}
int Channel::getFd()
{
    return fd_;
}
void Channel::useET()
{
    events_ |= EPOLLET;
}
void Channel::enableReading()
{
    events_ |= EPOLLIN;
    epfd_->updatechannel(this);
}
void Channel::setInEpoll()
{
    inepoll_ = true;
}
void Channel::setRevents(uint32_t ev)
{
    revents_ = ev;
}
bool Channel::inpoll()
{
    return inepoll_;
}
uint32_t Channel::getEvent()
{
    return events_;
}
uint32_t Channel::getRevent()
{
    return revents_;
}

void Channel::handleevent()
{
    if (revents_ & EPOLLRDHUP) // 对方已关闭，有些系统检测不到，可以使用EPOLLIN，recv()返回0。
    {
        printf("client(eventfd=%d) disconnected.\n", fd_);
        close(fd_); // 关闭客户端的fd。
    } //  普通数据  带外数据
    else if (revents_ & (EPOLLIN | EPOLLPRI)) // 接收缓冲区中有数据可以读。
    {
        readCallBack_();
    }
    else if (revents_ & EPOLLOUT) // 有数据需要写，暂时没有代码，以后再说。
    {
    }
    else // 其它事件，都视为错误。
    {
        printf("client(eventfd=%d) error.\n", fd_);
        close(fd_); // 关闭客户端的fd。
    }
}

void Channel::newconnection(Sock *serverSock)
{
    InetAddress clientaddr;
    Sock *clentSock = new Sock(serverSock->acceptNonBlocking(clientaddr));
    printf("accept client(fd=%d,ip=%s,port=%d) ok.\n", clentSock->getSock(), clientaddr.ip(), clientaddr.port());
    Channel *clientchannel = new Channel(epfd_, clentSock->getSock());
    clientchannel->setReadCallBack(std::bind(&Acceptor::onmessage, clientchannel));
    clientchannel->useET();
    clientchannel->enableReading();
}
void Channel::onmessage()
{
    char buffer[1024];
    while (true) // 由于使用非阻塞IO，一次读取buffer大小数据，直到全部的数据读取完毕。
    {
        bzero(&buffer, sizeof(buffer));
        ssize_t nread = read(fd_, buffer, sizeof(buffer));
        if (nread > 0) // 成功的读取到了数据。
        {
            // 把接收到的报文内容原封不动的发回去。
            printf("recv(eventfd=%d):%s\n", fd_, buffer);
            send(fd_, buffer, strlen(buffer), 0);
        }
        else if (nread == -1 && errno == EINTR) // 读取数据的时候被信号中断，继续读取。
        {
            continue;
        }
        else if (nread == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) // 全部的数据已读取完毕。
        {
            break;
        }
        else if (nread == 0) // 客户端连接已断开。
        {
            printf("client(eventfd=%d) disconnected.\n", fd_);
            close(fd_); // 关闭客户端的fd。
            break;
        }
        else
        {
        }
    }
}
void Channel::setReadCallBack(func_t fn)
{
    readCallBack_ = fn;
}


